/**
 * 格式化时间
 * @param {Date} date 日期对象
 * @param {String} options 自定义格式，可选，类似“yyyy-MM-dd hh:mm:ss”
 */
function formatTime(date,options) {
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()

  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds()
  if(/^[y]{2,}|[M]{2,}|[d]{2,}|[h]{2,}|[m]{2,}|[s]{2,}$/.test(options)){
    return options.replace(/yyyy/,year)
            .replace(/MM/,formatNumber(month))
            .replace(/dd/,formatNumber(day))
            .replace(/hh/,formatNumber(hour))
            .replace(/mm/,formatNumber(minute))
            .replace(/ss/,formatNumber(second));
  }

  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
/**
 * 倒计时计算
 * @param {Date} endDate 截止时间
 * @param {String} options 模板字符串，类似“距离结束还有dd天hh小时mm分钟ss秒”
 */
function countDown(endDate,options){
  if(type(endDate)!="Date"){
    console.error("倒计时数据类型错误!");
    return;
  }
  let timeScope = endDate - new Date();
  let day = ~~(timeScope/(60*60*24*1000));
  let hour = ~~(timeScope/(60*60*1000)%24);
  let minute = ~~(timeScope/(60*1000)%60);
  let second = ~~(timeScope/1000%60);
  if(timeScope<=0){    //倒计时不能为负数，最多为0
    day = hour = minute = second = 0;
  }
  if(/^[d]{2,}|[h]{2,}|[m]{2,}|[s]{2,}$/.test(options)){
    return options.replace(/dd/,formatNumber(day))
          .replace(/hh/,formatNumber(hour))
          .replace(/mm/,formatNumber(minute))
          .replace(/ss/,formatNumber(second));
  }

  return {
          day:formatNumber(day.toString()),
          hour:formatNumber(hour.toString()),
          minute:formatNumber(minute.toString()),
          second:formatNumber(second.toString())
        };  //如果没传模板字符串，直接返回对象值
}
/**
 * 类型检测
 * @param {any} v 
 */
function type(v){
  return Object.prototype.toString.call(v).slice(8,-1);
}

function formatNumber(n) {
  n = n.toString()
  return n[1] ? n : '0' + n
}
/**
 * 回调转promise
 * @param {function} fn   要转化的函数，要求必须含有success和fail回调的参数对象， 
 * 例子 promisefy(wx.showToast)({title:'加载中'}).then(res=>console.log('success')).catch(err=>console.log('fail'))
 */
function promisefy(fn){
	return function(){
    let [ob,...rest] = arguments;
		if(typeof ob == "object" || typeof ob == "undefined"){  //传入对象，或没传值
			return new Promise((resolve,reject)=>{
				fn({
					...ob,
					success(res){
						resolve(res);
					},fail(res){
						reject(res);
					}
				},...rest); //额外参数
			});
		}
		throw new Error("canot find 'success' and 'fail' at arguments of fn!")
	}
}
/**
 * 检测授权
 * @param {string} scope 类似'scope.userInfo'	
 * scope.userInfo		wx.getUserInfo	用户信息
 * scope.userLocation	wx.getLocation, wx.chooseLocation	地理位置
 * scope.userLocationBackground	wx.startLocationUpdateBackground	后台定位
 * scope.address		wx.chooseAddress	通讯地址
 * scope.invoiceTitle	wx.chooseInvoiceTitle	发票抬头
 * scope.invoice		wx.chooseInvoice	获取发票
 * scope.werun		wx.getWeRunData	微信运动步数
 * scope.record		wx.startRecord	录音功能
 * scope.writePhotosAlbum	wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum	保存到相册
 * scope.camera		camera 组件	摄像头
 * @param {string} title 授权失败时候的提示信息，例如：检测到您未开启xx授权，是否前往开启？
 */
function checkAuth(scope,title){
  let getSetting = promisefy(wx.getSetting);
  let showModal = promisefy(wx.showModal);
  let authorize = promisefy(wx.authorize);
  getSetting().then(res=>{
    if(!res.authSetting[scope]){
      authorize({scope}).catch(res=>{   //授权失败
        return showModal({
          title:title,
          confirmText:"前往",
          cancelText:"返回",
        })
      }).then(res=>wx.openSetting())  //确认打开授权设置手动开启
        .catch(res=>wx.navigateBack())  //拒绝则原路返回
    }
  })
}

// 深度拷贝对象，不含函数和正则
function deepClone(obj) {
  let objClone = JSON.parse(JSON.stringify(obj));
  return objClone
}

//拨打电话
function makeCallphone(mobile) {
  wx.showModal({
    title: '',
    content: mobile,
    confirmText: '拨打',
    confirmColor: '#48C23D',
    success: function (res) {
      if (res.confirm) {
        wx.makePhoneCall({
          phoneNumber: mobile,
          success: function () {
            console.log("拨打电话成功！")
          },
          fail: function () {
            console.log("拨打电话失败！")

          }
        })
      }
    }
  })
}

//数组分组
function splitArrData(arr, pageNum) {
  var i = 0;
  var page = Math.ceil(arr.length / pageNum);
  var newArr = [];
  for (var i = 0; i < page; i++) {
    var curarr = [];
    curarr = arr.slice(i * pageNum, (i * pageNum + pageNum));
    newArr.push(curarr);
  }
  return newArr;
}

// 格式化音乐进度显示时间
function formatPlayTime(time) {
  var minute = parseInt(time / 60);
  var second = parseInt((time % 60));
  second = second < 10 ? '0' + second : second;
  var showTime = minute + ':' + second;
  return showTime;
}

// 计算两点之间距离
function getFlatternDistance(lat1, lng1, lat2, lng2) {
  const EARTH_RADIUS = 6378137.0;//单位m
  var f = getRad((lat1 + lat2) / 2);
  var g = getRad((lat1 - lat2) / 2);
  var l = getRad((lng1 - lng2) / 2);
  var sg = Math.sin(g);
  var sl = Math.sin(l);
  var sf = Math.sin(f);
  var s, c, w, r, d, h1, h2;
  var a = EARTH_RADIUS;
  var fl = 1 / 298.257;
  sg = sg * sg;
  sl = sl * sl;
  sf = sf * sf;
  s = sg * (1 - sl) + (1 - sf) * sl;
  c = (1 - sg) * (1 - sl) + sf * sl;
  w = Math.atan(Math.sqrt(s / c));
  r = Math.sqrt(s * c) / w;
  d = 2 * w * a;
  h1 = (3 * r - 1) / 2 / c;
  h2 = (3 * r + 1) / 2 / s;
  return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg)) / 1000;
}

//经纬度转换成三角函数中度分表形式。
function getRad(d) {
  return d * Math.PI / 180.0;
}

// 根据距离给列表排序
function sortArr(property) {
  return function (a, b) {
    var value1 = a[property];
    var value2 = b[property];
    return value1 - value2;
  }
}

// 检测更新
function checkUpdate(){
  return new Promise((resolve,reject)=>{
    const updateManager = wx.getUpdateManager();
    updateManager.onCheckForUpdate(function (res) {
      // 请求完新版本信息的回调
      console.info('是否有版本更新：',res.hasUpdate);
      resolve({hasUpdate:res.hasUpdate});
    })
  
    updateManager.onUpdateReady(function () {
      wx.showModal({
        title: '更新提示',
        content: '新版本已经准备好，是否重启应用？',
        success: function (res) {
          if (res.confirm) {
            // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
            updateManager.applyUpdate();
          }
        }
      })
    })
    updateManager.onUpdateFailed(function () {
      // 新版本下载失败
      console.info('更新下载失败');
      reject('新版本下载失败');
    })

  })
}

module.exports = {
  formatTime,   //时间格式化
  countDown,    //倒计时计算
  type,         //类型检测
  promisefy,    //promise化wx api
  checkAuth,    //检测授权
  deepClone,    //深拷贝
  makeCallphone, //拨打电话
  splitArrData , //数组分组
  formatPlayTime, //格式化播放时间
  getFlatternDistance,  //计算两点间距离
  sortArr,        //数组按指定条件排序
  checkUpdate,    //版本更新检测
}
